package com.zyf.EasyNet.service.impl;

import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.zyf.EasyNet.model.UserHistory;
import com.zyf.EasyNet.param.UserHistoryQueryParam;
import com.zyf.EasyNet.service.UserHistoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.function.LongSupplier;

/**
 * @first_author zyflzz
 * @gmt_created 2022/6/3
 * @gmt_modified 2022/6/3
 */
@Service
public class UserHistoryServiceImpl implements UserHistoryService {

    private static final Logger LOG = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 添加用户
     *
     * @param userHistory 被添加的用户
     * @return 被添加的用户
     */
    @Override
    public UserHistory add(UserHistory userHistory) {
        // 作为服务，要对入参进行判断，不能假设被调用时传入的一定是真正的对象
        if (userHistory == null || userHistory.getUserName().equals("")) {
            LOG.error("input User data is null.");
            return null;
        }

        return mongoTemplate.insert(userHistory);
    }

    /**
     * 获取用户
     * 注意输入不能为空，为空则返回 null
     *
     * @param id 用户 id
     * @return 如果用户存在，返回获取到的用户；如果用户不存在或输入错误，返回你 null
     */
    @Override
    public UserHistory get(long id) {
        if (id < 0) {
            LOG.error("input user Id is blank.");
            return null;
        }

        UserHistory userHistory = mongoTemplate.findById(id, UserHistory.class);
        return userHistory;
    }

    /**
     * 用来查询用户
     *
     * @param param 需要查询的对象
     * @return Page<User> 分页对象
     */
    @Override
    public Page<UserHistory> list(UserHistoryQueryParam param) {
        // 作为服务，要对入参进行判断，不能假设被调用时，入参一定正确
        if (param == null) {
            LOG.error("list : input User data is not correct.");
            return null;
        }

        // 总查询条件
        Criteria criteria = new Criteria();
        // 可能有多个子条件，可能按照 id、 loginName 、 password 、 mobile 、姓名、车牌号、身份查询
        List<Criteria> subCris = new ArrayList();
        if (StringUtils.hasText(param.getUserName())) {
            subCris.add(Criteria.where("userName").is(param.getUserName()));
            LOG.info("list get userName");
        }

        if (StringUtils.hasText(param.getNickName())) {
            subCris.add(Criteria.where("nickName").is(param.getNickName()));
        }

        // 必须至少有一个查询条件
        if (subCris.isEmpty()) {
            LOG.error("There must be at least one query condition");
            return null;
        }

        // 子条件以 and 关键词连接成总条件对象
        criteria.andOperator(subCris.toArray(new Criteria[]{}));

        // 将条件对象构建查询对象
        Query query = new Query(criteria);
        // 获取查询到总数
        long count = mongoTemplate.count(query, UserHistory.class);
        // 构建分页对象，对象页码号是从 0 开始计数的，pageNum 是从1开始的
        Pageable pageable = PageRequest.of(param.getPageNum() - 1, param.getPageSize());
        query.with(pageable);

        // 获取查询结果
        List<UserHistory> userHistories = mongoTemplate.find(query, UserHistory.class);
        // 构建分页器
        Page<UserHistory> pageResult = PageableExecutionUtils.getPage(userHistories, pageable, new LongSupplier() {
            @Override
            public long getAsLong() {
                return count;
            }
        });

        return pageResult;
    }

    /**
     * 修改用户数据
     *
     * @param userHistory 修改后的用户
     * @return 修改成功返回 true，失败返回 false
     */
    @Override
    public boolean modify(UserHistory userHistory) {
        // 作为服务，要对入参进行判断，不能假设被调用时，入参一定正确
        if (userHistory == null || userHistory.getId() < 0L) {
            LOG.error("modify : input User data is not correct.");
            return false;
        }

        // 主键不能修改，作为查询条件
        Query query = new Query(Criteria.where("id").is(userHistory.getId()));

        // 记录修改次数
        int count = 0;
        Update updateData = new Update();
        // 值为 null 表示不修改，值为长度为 0 的字符串 "" 表示清空此字段
        if (userHistory.getUserName() != null && !userHistory.getUserName().equals("")) {
            updateData.set("userName", userHistory.getUserName());
            count++;
        }

        if (userHistory.getNickName() != null && !userHistory.getNickName().equals("")) {
            updateData.set("nickName", userHistory.getNickName());
            count++;
        }

        if (count == 0){
            LOG.error("There must be at least one modify condition");
            return false;
        }

        // 获取一条符合条件的记录，并修改其字段
        UpdateResult result = mongoTemplate.updateFirst(query, updateData, UserHistory.class);
        return result.getModifiedCount() > 0;
    }

    /**
     * 删除用户数据
     *
     * @param id 被删除用户的 id
     * @return 删除成功返回 true，失败返回 false
     */
    @Override
    public boolean delete(long id) {
        // 输入的主键 id 必须有文本，不能为空或全空格
        if (id < 0) {
            LOG.error("input user Id is blank.");
            return false;
        }

        UserHistory userHistory = new UserHistory();
        userHistory.setId(id);

        DeleteResult result = mongoTemplate.remove(userHistory);
        return result.getDeletedCount() > 0;
    }

}
